/**
 *  (c)
 * <p>
 *
 * <p>
 *
 */

package com.nn.smart.bus.controller;

import com.nn.smart.bus.cloud.AbstractCloudStorageService;
import com.nn.smart.bus.cloud.AliyunCloudStorageService;
import com.nn.smart.bus.cloud.CloudStorageConfig;
import com.nn.smart.bus.cloud.OssFactory;
import com.nn.smart.bus.commons.tools.page.PageData;
import com.nn.smart.bus.commons.tools.utils.Result;
import com.nn.smart.bus.dto.UploadDTO;
import com.nn.smart.bus.dto.UploadFormDTO;
import com.nn.smart.bus.dto.UploadToOssDTO;
import com.nn.smart.bus.entity.OssEntity;
import com.nn.smart.bus.enums.OssTypeEnum;
import com.nn.smart.bus.exception.ModuleErrorCode;
import com.nn.smart.bus.service.OssService;
import com.nn.smart.bus.utils.ModuleConstant;
import com.nn.smart.bus.commons.tools.annotation.LogOperation;
import com.nn.smart.bus.commons.tools.constant.NumConstant;
import com.nn.smart.bus.commons.tools.validator.ValidatorUtils;
import com.nn.smart.bus.commons.tools.validator.group.AliyunGroup;
import com.nn.smart.bus.commons.tools.validator.group.QcloudGroup;
import com.nn.smart.bus.commons.tools.validator.group.QiniuGroup;
import com.nn.smart.bus.remote.ParamsRemoteService;
import com.google.gson.Gson;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.apache.commons.io.FilenameUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
import springfox.documentation.annotations.ApiIgnore;
import sun.misc.BASE64Decoder;

import javax.servlet.http.HttpServletResponse;
import java.util.Arrays;
import java.util.Map;

/**
 * 文件上传
 *
 * @author nanning
 */
@RestController
@RequestMapping("file")
@Api(tags = "文件上传")
public class OssController {

    @Autowired
    private OssService ossService;

    @Autowired
    private ParamsRemoteService paramsRemoteService;

    private final static String KEY = ModuleConstant.CLOUD_STORAGE_CONFIG_KEY;

    @GetMapping("page")
    @ApiOperation(value = "分页")
    public Result<PageData<OssEntity>> page(@ApiIgnore @RequestParam Map<String, Object> params) {
        PageData<OssEntity> page = ossService.page(params);

        return new Result<PageData<OssEntity>>().ok(page);
    }

    @GetMapping("info")
    @ApiOperation(value = "云存储配置信息")
    public Result<CloudStorageConfig> info() {
        CloudStorageConfig config = paramsRemoteService.getValueObject(KEY, CloudStorageConfig.class);

        return new Result<CloudStorageConfig>().ok(config);
    }

    @PostMapping
    @ApiOperation(value = "保存云存储配置信息")
    @LogOperation("保存云存储配置信息")
    public Result saveConfig(@RequestBody CloudStorageConfig config) {
        //校验类型
        ValidatorUtils.validateEntity(config);

        if (config.getType() == OssTypeEnum.QINIU.value()) {
            //校验七牛数据
            ValidatorUtils.validateEntity(config, QiniuGroup.class);
        } else if (config.getType() == OssTypeEnum.ALIYUN.value()) {
            //校验阿里云数据
            ValidatorUtils.validateEntity(config, AliyunGroup.class);
        } else if (config.getType() == OssTypeEnum.QCLOUD.value()) {
            //校验腾讯云数据
            ValidatorUtils.validateEntity(config, QcloudGroup.class);
        }

        paramsRemoteService.updateValueByCode(KEY, new Gson().toJson(config));

        return new Result();
    }

    @PostMapping("upload")
    @ApiOperation(value = "上传文件")
    public Result<UploadDTO> upload(@RequestParam("file") MultipartFile file) throws Exception {
        if (file.isEmpty()) {
            return new Result<UploadDTO>().error(ModuleErrorCode.UPLOAD_FILE_EMPTY);
        }

        //上传文件
        String extension = FilenameUtils.getExtension(file.getOriginalFilename());
        String url = OssFactory.build().uploadSuffix(file.getBytes(), extension);
        return ossService.afterUpload(url, file.getSize());
    }

    /**
     * 下载阿里云oss服务器上的文件
     *
     * @param fileUrl  完整的访问链接
     * @param response 浏览器返回
     * @return void
     * @author nanning
     */
    @GetMapping("download")
    public void download(String fileUrl, HttpServletResponse response) throws Exception {
        AbstractCloudStorageService build = OssFactory.build();
        if (build instanceof AliyunCloudStorageService) {
            AliyunCloudStorageService aliyunCloudStorageService = (AliyunCloudStorageService) build;
            aliyunCloudStorageService.download(fileUrl, response);
        } else {
            ossService.download(fileUrl, response);
        }
    }


    @DeleteMapping
    @ApiOperation(value = "删除")
    @LogOperation("删除")
    public Result delete(@RequestBody Long[] ids) {
        ossService.deleteBatchIds(Arrays.asList(ids));

        return new Result();
    }

    @PostMapping("uploadBase64")
    @ApiOperation(value = "上传文件")
    public Result<String> uploadFile(@RequestBody UploadFormDTO formDTO) throws Exception {
        if (null == formDTO || StringUtils.isEmpty(formDTO.getBase64String())) {
            return new Result<String>().error(ModuleErrorCode.UPLOAD_FILE_EMPTY);
        }
        String[] base64ImgArr = formDTO.getBase64String().split(",");
        String suffixTmp = base64ImgArr[0];
        String suffix = suffixTmp.substring(11, suffixTmp.indexOf(";"));
        byte[] imgBytes = new BASE64Decoder().decodeBuffer(base64ImgArr[1]);
        String url = OssFactory.build().uploadSuffix(imgBytes, suffix);
        return new Result<String>().ok(url);
    }

    @PostMapping("uploadFile")
    public Result<String> uploadFile(@RequestBody UploadToOssDTO dto) {
        byte[] fileByte = dto.getFileByte();
        if (null == fileByte || fileByte.length == NumConstant.ZERO) {
            return new Result().error(ModuleErrorCode.UPLOAD_FILE_EMPTY);
        }
        //上传文件
        String extension = FilenameUtils.getExtension(dto.getFileName());
        String url = OssFactory.build().uploadSuffix(fileByte, extension);

        return new Result().ok(url);
    }

}
